

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include "utils.h"
#include <time.h>

#define MAX_LISTENQUEUELEN 20   ///< The maximum number of queued connections.
#define doLoggingS 2

int handle_command(int sock, char *cmd) {

    char buffer[50];
    strcpy(buffer, "Processing command '");
    strcat(buffer, cmd);
    strcat(buffer, "'\n");
    logger(serverFile, buffer, doLoggingS); // logger

    // For now, just send back the command to the client.
    sendall(sock, cmd, strlen(cmd));
    sendall(sock, "\n", 1);

    return 0;
}

int main(int argc, char *argv[]) {
    // Process command line arguments.
    // This program expects exactly one argument: the config file name.


	if(doLoggingS==2){ 			//Log to file?
    time_t basetime;
    struct tm * conTime;
    char sFile[50];
    char FileSS[50];

    basetime = time(NULL);
    conTime = localtime(&basetime);
    strftime(sFile, sizeof(sFile), "Server-%Y-%m-%d-%H-%M-%S.log",conTime);
    //Generate filename

    serverFile = fopen(sFile, "w");	//Open file
	}

    char buffer[50];
    char buffer2[50];

    assert(argc > 0);
    if (argc != 2) {
        printf("Usage %s <config_file>\n", argv[0]);
        //closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }
    char *config_file = argv[1];

    // Read the config file.
    struct config_params params;
    int status = read_config(config_file, &params);
    if (status != 0) {
        printf("Error processing config file.\n");
        closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }

    // SOON: LOL, YOU CAN JUST USE 1 SPRINTF() FOR THESE
    strcpy(buffer, "Server on ");
    strcat(buffer, params.server_host);
    sprintf(buffer2, ":%d\n", params.server_port);
    strcat(buffer, buffer2);
    logger(serverFile, buffer, doLoggingS); //logger

    // Create a socket.
    int listensock = socket(PF_INET, SOCK_STREAM, 0);
    if (listensock < 0) {
        printf("Error creating socket.\n");
        closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }

    // Allow listening port to be reused if defunct.
    int yes = 1;
    status = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
    if (status != 0) {
        printf("Error configuring socket.\n");
        closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }

    // Bind it to the listening port.
    struct sockaddr_in listenaddr;
    memset(&listenaddr, 0, sizeof listenaddr);
    listenaddr.sin_family = AF_INET;
    listenaddr.sin_port = htons(params.server_port);
    inet_pton(AF_INET, params.server_host, &(listenaddr.sin_addr)); // bind to local IP address
    status = bind(listensock, (struct sockaddr*) &listenaddr, sizeof listenaddr);
    if (status != 0) {
        printf("Error binding socket.\n");
        closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }

    // Listen for connections.
    status = listen(listensock, MAX_LISTENQUEUELEN);
    if (status != 0) {
        printf("Error listening on socket.\n");
        closeS(doLoggingS);
        exit(EXIT_FAILURE);
    }

    // Listen loop.
    int wait_for_connections = 1;
    while (wait_for_connections) {
        // Wait for a connection.
        struct sockaddr_in clientaddr;
        socklen_t clientaddrlen = sizeof clientaddr;
        int clientsock = accept(listensock, (struct sockaddr*) &clientaddr, &clientaddrlen);
        if (clientsock < 0) {
            printf("Error accepting a connection.\n");
            closeS(doLoggingS);
            exit(EXIT_FAILURE);
        }

        strcpy(buffer, "Got a connection from ");
        strcat(buffer, inet_ntoa(clientaddr.sin_addr));
        sprintf(buffer2, ":%d.\n", clientaddr.sin_port);
        strcat(buffer, buffer2);
        logger(serverFile, buffer, doLoggingS); //logger

        // Get commands from client.
        int wait_for_commands = 1;
        do {
            // Read a line from the client.
            char cmd[MAX_CMD_LEN];
            int status = recvline(clientsock, cmd, MAX_CMD_LEN);
            if (status != 0) {
                // Either an error occurred or the client closed the connection.
                wait_for_commands = 0;
            } else {
                // Handle the command from the client.
                int status = handle_command(clientsock, cmd);
                if (status != 0)
                    wait_for_commands = 0; // Oops.  An error occured.
            }
        } while (wait_for_commands);

        // Close the connection with the client.
        close(clientsock);
        strcpy(buffer, "Closed connection from ");
        strcat(buffer, inet_ntoa(clientaddr.sin_addr));
        sprintf(buffer2, ":%d\n", clientaddr.sin_port);
        strcat(buffer, buffer2);
        logger(serverFile, buffer, doLoggingS); //logger
    }

    // Stop listening for connections.
    close(listensock);

    closeS(doLoggingS);
    return EXIT_SUCCESS;
}

